package com.university.mentalhealthplatform.global.rbac.service.relation;

import com.university.mentalhealthplatform.global.rbac.dto.normal.RoleDTO;
import com.university.mentalhealthplatform.global.rbac.dto.normal.BaseUserDTO;
import com.university.mentalhealthplatform.global.rbac.model.Role;
import com.university.mentalhealthplatform.global.rbac.model.User;
import com.university.mentalhealthplatform.global.rbac.repository.RoleRepository;
import com.university.mentalhealthplatform.global.rbac.repository.BaseUserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class UserRoleService {

    @Autowired
    private BaseUserRepository baseUserRepository;

    @Autowired
    private RoleRepository roleRepository;

    // 为用户绑定角色
    public User bindRolesToUser(UUID userId, List<Long> roleIds) {
        User user = baseUserRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("User not found"));

        List<Role> roles = roleRepository.findAllById(roleIds);
        if (roles.isEmpty()) {
            throw new RuntimeException("Roles not found");
        }

        // 将 List<Role> 转换为 Set<Role>
        Set<Role> roleSet = new HashSet<>(roles);

        user.setRoles(roleSet);
        return baseUserRepository.save(user);
    }


    /**
     * 为用户分配角色。
     *
     * @param userId 用户的唯一标识符（ID）
     * @param roleId 角色的唯一标识符（ID）
     * @return 更新后的用户对象，包含分配的新角色
     * @throws RuntimeException 如果用户或角色未找到，抛出运行时异常
     */
    public User assignRoleToUser(UUID userId, Long roleId) {
        User user = baseUserRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("User not found"));
        Role role = roleRepository.findById(roleId)
                .orElseThrow(() -> new RuntimeException("Role not found"));
        user.getRoles().add(role);
        return baseUserRepository.save(user);
    }

    // 获取单个用户及其角色
    public BaseUserDTO getUserById(UUID userId) {
        User user = baseUserRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        return convertToUserDTO(user);
    }

    // 获取所有用户及其角色
    public List<BaseUserDTO> getAllUsers() {
        List<User> users = baseUserRepository.findAll();
        return users.stream()
                .map(this::convertToUserDTO)
                .collect(Collectors.toList());
    }

    // 将 User 转换为 UserDTO
    private BaseUserDTO convertToUserDTO(User user) {
        Set<RoleDTO> roleDTOs = user.getRoles().stream()
                .map(this::convertToRoleDTO)
                .collect(Collectors.toSet());

        return new BaseUserDTO(user.getId(), user.getUsername(), user.isStatus(), roleDTOs);
    }

    // 将 Role 转换为 RoleDTO
    private RoleDTO convertToRoleDTO(Role role) {
        return new RoleDTO(role);
    }

    // 授予角色给用户
    public void addRoleToUser(UUID userId, Long roleId) {
        // 获取用户
        User user = baseUserRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        // 获取角色
        Role role = roleRepository.findById(roleId)
                .orElseThrow(() -> new RuntimeException("角色不存在"));

        // 授予角色
        user.getRoles().add(role);

        // 保存更新后的用户
        baseUserRepository.save(user);
    }

    // 撤销用户的角色
    public void removeRoleFromUser(UUID userId, Long roleId) {
        // 获取用户
        User user = baseUserRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        // 获取角色
        Role role = roleRepository.findById(roleId)
                .orElseThrow(() -> new RuntimeException("角色不存在"));

        // 撤销角色
        user.getRoles().remove(role);

        // 保存更新后的用户
        baseUserRepository.save(user);
    }
}
